package com.yaodian100.core.admin.web;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.lang.xwork.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.yaodian100.core.admin.entity.Group;
import com.yaodian100.core.admin.entity.Role;
import com.yaodian100.core.admin.entity.User;
import com.yaodian100.core.admin.service.GroupService;
import com.yaodian100.core.admin.service.RoleService;
import com.yaodian100.core.admin.service.UserService;
import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.menu.entity.Menu;
import com.yaodian100.core.menu.service.MenuService;
import com.yaodian100.ec.common.web.AbstractAction;

/**
 * @author Tina.xu
 * 
 */
public class AccountAction extends AbstractAction {

	/** serialVersionUID */
	private static final long serialVersionUID = 4281715524222814657L;
	/** logger */
	private final Logger logger = LoggerFactory.getLogger(AccountAction.class);
	@Autowired
	private UserService userService;
	@Autowired
	private GroupService groupService;
	@Autowired
	private MenuService menuService;

	private Menu userStatus;
	private List<Group> groups;
	private List<Role> otherRoles;
	private List<Role> managerRoles;
	private List<User> users;
	private String usernameParam;
	private String emailParam;
	private String groupParam;
	private List<String> statusParam = new ArrayList();

	private User user;
	private String groupCode;
	private String username;
	private String[] grantManageRoles;
	private String[] grantOtherRoles;

	private Map<Role.Type, String> roleTypes = new TreeMap<Role.Type, String>();
	private List<Role> roles;
	private String roletypeParam;
	private String roleParam;
	@Autowired
	private RoleService roleService;
	private String codeKey;

	/** default constructor */
	public AccountAction() {
	}

	/**
	 * @param userService the userService to set
	 */

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public void setCodeKey(String codeKey) {
		this.codeKey = codeKey;
	}

	/**
	 * @param groupService the groupService to set
	 */
	public void setGroupService(GroupService groupService) {
		this.groupService = groupService;
	}

	/**
	 * @return the usernameParam
	 */
	public String getUsernameParam() {
		return usernameParam;
	}

	/**
	 * @param usernameParam the usernameParam to set
	 */
	public void setUsernameParam(String usernameParam) {
		this.usernameParam = usernameParam;
	}

	/**
	 * @return the userStatus
	 */
	public Menu getUserStatus() {
		return userStatus;
	}

	/**
	 * @param userStatus the userStatus to set
	 */
	public void setUserStatus(Menu userStatus) {
		this.userStatus = userStatus;
	}

	/**
	 * @return the emailParam
	 */
	public String getEmailParam() {
		return emailParam;
	}

	/**
	 * @param emailParam the emailParam to set
	 */
	public void setEmailParam(String emailParam) {
		this.emailParam = emailParam;
	}

	/**
	 * @return the groupParam
	 */
	public String getGroupParam() {
		return groupParam;
	}

	/**
	 * @param groupParam the groupParam to set
	 */
	public void setGroupParam(String groupParam) {
		this.groupParam = groupParam;
	}

	/**
	 * @return the statusParam
	 */
	public List<String> getStatusParam() {
		return statusParam;
	}

	/**
	 * @param statusParam the statusParam to set
	 */
	public void setStatusParam(List<String> statusParam) {
		this.statusParam = statusParam;
	}

	/**
	 * @return the users
	 */
	public List<User> getUsers() {
		return users;
	}

	/**
	 * @param users the users to set
	 */
	public void setUsers(List<User> users) {
		this.users = users;
	}

	public String list() {
		return "list";
	}

	public String view() {
		if (StringUtils.isNotEmpty(username)) {
			try {
				user = userService.get(username);
				if (user == null) {
					addActionError("使用者不存在, 帐号:" + username);
					return "list";
				}
				if (!user.getGroupName().startsWith(codeKey)) {
					user = null;
					addActionError("使用者不存在, 帐号:" + username);
					return "list";
				}
				groupCode = user.getGroupName();
				List<String> mRole = new ArrayList();
				List<String> oRole = new ArrayList();
				for (Role r : user.getRoles()) {
					switch (r.getType()) {
					case MANAGER:
						mRole.add(r.getName());
						break;
					case OTHER:
						oRole.add(r.getName());
						break;
					}
				}
				grantManageRoles = mRole.toArray(new String[0]);
				grantOtherRoles = oRole.toArray(new String[0]);
			} catch (Exception e) {
				addActionError(e.getMessage());
				e.printStackTrace();
			}
			return "view";
		} else {
			addActionError("使用者不存在, 帐号:" + username);
			return "list";
		}
	}

	public String edit() {
		return "edit";
	}

	public String delete() {
		try {
			System.out.println(user.toString());
			if (user != null) {
				userService.delete(user);
				addActionMessage("删除成功");
			} else {
				addActionError("使用者不存在, 未删除");
			}
		} catch (Exception e) {
			addActionError("删除失败");
			e.printStackTrace();
			return "view";
		}
		return search();
	}

	public String resetPasswd() {
		try {
			if (user != null) {
				userService.resetPassword(user);
				addActionMessage("重设密码成功");
			}
		} catch (Exception e) {
			addActionError(e.getMessage());
			e.printStackTrace();
			return "view";
		}
		return "view";
	}

	public String add() {
		user = new User("");
		grantManageRoles = null;
		grantOtherRoles = null;
		return "edit";
	}

	public String save() {
		try {
			if (user != null) {
				List<String> userRoleName = new ArrayList();
				Iterator<Role> it = user.getRoles().iterator();
				while (it.hasNext()) {
					Role r = it.next();
					if (Arrays.binarySearch(grantManageRoles, r.getName()) != 0 && Role.Type.MANAGER.equals(r.getType())) {
						// 移除權限為 Manager, 但是代碼不相同
						it.remove();
					} else if (Arrays.binarySearch(grantOtherRoles, r.getName()) != 0 && Role.Type.OTHER.equals(r.getType())) {
						// 移除權限為 Other, 但是代碼不相同
						it.remove();
					} else if (Role.Type.GROUP.equals(r.getType()) && !r.getKey().equals(groupCode)) {
						// 移除權限為 Group, 但是部門代碼不相同
						it.remove();
					} else {
						userRoleName.add(r.getName());
					}
				}

				for (int i = 0; i < grantManageRoles.length; i++) {
					if (Collections.frequency(userRoleName, grantManageRoles[i]) == 0) {
						logger.info("add role:{}", grantManageRoles[i]);
						Role r = roleService.get(grantManageRoles[i]);
						if (r != null) {
							user.getRoles().add(r);
						}
					}
				}
				for (int i = 0; i < grantOtherRoles.length; i++) {
					if (Collections.frequency(userRoleName, grantOtherRoles[i]) == 0) {
						logger.info("add role:{}", grantOtherRoles[i]);
						Role r = roleService.get(grantOtherRoles[i]);
						if (r != null) {
							user.getRoles().add(r);
						}
					}
				}

				logger.debug("roles:{}", user.getRoles());
				if (user.getModifyDate() == null) {
					user = userService.createUser(user, null, groupCode);
				} else {
					if (!groupCode.equals(user.getGroupName())) {
						Group newGroup = groupService.get(groupCode);
						user.setGroup(newGroup);
						user.getRoles().add(newGroup.getRole());
					}
					user = userService.save(user);
				}
			} else {
				addActionError("使用者不存在");
				return "list";
			}
		} catch (Exception e) {
			addActionError(e.getMessage());
			e.printStackTrace();
			return "edit";
		}
		return "view";
	}

	public String search() {
		CommonCriteria cri = new CommonCriteria();
		if (StringUtils.isNotEmpty(usernameParam)) {
			cri.addRlike("username", usernameParam);
		}
		if (StringUtils.isNotEmpty(groupParam)) {
			cri.addRlike("group.code", groupParam);
		}
		if (statusParam != null && statusParam.size() > 0) {
			cri.addIn("status", statusParam);
		}
		if (StringUtils.isNotEmpty(emailParam)) {
			cri.addRlike("email", emailParam);
		}

		Role.Type roleType = null;
		String roleKey = null;
		if (StringUtils.isNotEmpty(this.roleParam)) {
			roleKey = this.roleParam;
		} else {
			if (StringUtils.isNotEmpty(this.roletypeParam)) {
				roleType = Role.Type.valueOf(this.roletypeParam);
			}
		}

		try {
			// 仅维护 crm user (C. 开头)
			cri.addIn("group.type", Arrays.asList(codeKey));
			int entitySize = userService.getListSizeByRole(cri, roleType, roleKey).intValue();
			getPager().setTotalSize(entitySize);
			users = userService.getListByRole(getPager().getCurrentPage() * getPager().getPageRecord(), getPager()
					.getPageRecord(), cri, null, roleType, roleKey);
			logger.info("pager:{},users:{}", getPager(), users);
			if (users.isEmpty()) {
				addActionMessage("查无资料");
			}
		} catch (CoreException e) {
			addActionError(e.getMessage());
			e.printStackTrace();
		}
		return "list";
	}

	public synchronized String listRoles() {
		CommonCriteria cri = new CommonCriteria();
		if (StringUtils.isNotEmpty(this.roletypeParam)) {
			Role.Type t = Role.Type.valueOf(this.roletypeParam);
			cri.addEq("type", t);
		}

		String[] sort;
		if (this.roletypeParam.equals(Role.Type.MANAGER.getCode())) {
			sort = null;
		} else {
			sort = new String[] { "key" };
		}

		this.roles = this.roleService.getList(0, -1, cri, sort);

		if (this.roletypeParam.equals(Role.Type.MANAGER.getCode())) {
			for (int i = this.roles.size(); i > 0; i--) {
				Role r = roles.get(i - 1);
				if (!r.getKey().startsWith(codeKey)) {
					roles.remove(i - 1);
				}
			}
		}

		if (this.roletypeParam.equals(Role.Type.OTHER.getCode())) {
			for (int i = this.roles.size(); i > 0; i--) {
				Role r = roles.get(i - 1);
				if (!r.getDescription().equals("一般使用者")) {
					roles.remove(i - 1);
				}
			}
		}
		return "jsonGetRoles";
	}

	@Override
	public void prepare() throws Exception {
		super.prepare();
		clearErrorsAndMessages();

		if (otherRoles == null) {
			CommonCriteria cri = new CommonCriteria();
			cri.addEq("type", Role.Type.OTHER);
			otherRoles = roleService.getList(0, -1, cri, new String[] { "key" });
			for (int i = this.otherRoles.size(); i > 0; i--) {
				Role r = otherRoles.get(i - 1);
				if (!r.getDescription().equals("一般使用者")) {
					otherRoles.remove(i - 1);
				}
			}
		}

		if (managerRoles == null) {
			CommonCriteria cri = new CommonCriteria();
			cri.addEq("type", Role.Type.MANAGER);
			managerRoles = roleService.getList(0, -1, cri, null);
			for (int i = managerRoles.size(); i > 0; i--) {
				Role r = managerRoles.get(i - 1);
				if (!r.getKey().startsWith(codeKey)) {
					managerRoles.remove(i - 1);
				}
			}
		}

		if (userStatus == null) {
			userStatus = menuService.get("User.status");
			logger.debug("new user status:{}", userStatus);
		}

		if (groups == null) {
			CommonCriteria cri = new CommonCriteria();
			cri.addIn("type", Arrays.asList(codeKey));
			groups = groupService.getList(0, -1, cri, new String[] { "code asc" });
		}

		if (roleTypes.size() == 0) {
			roleTypes.put(Role.Type.OTHER, "一般角色");
			roleTypes.put(Role.Type.MANAGER, "主管角色");
		}
	}

	public Map<Role.Type, String> getRoleTypes() {
		return roleTypes;
	}

	public void setRoleTypes(Map<Role.Type, String> roleTypes) {
		this.roleTypes = roleTypes;
	}

	public List<Group> getGroups() {
		return groups;
	}

	public void setGroups(List<Group> groups) {
		this.groups = groups;
	}

	public List<Role> getRoles() {
		return roles;
	}

	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}

	public String getRoletypeParam() {
		return roletypeParam;
	}

	public void setRoletypeParam(String roletypeParam) {
		this.roletypeParam = roletypeParam;
	}

	public String getRoleParam() {
		return roleParam;
	}

	public void setRoleParam(String roleParam) {
		this.roleParam = roleParam;
	}

	public String getGroupCode() {
		return groupCode;
	}

	public void setGroupCode(String groupCode) {
		this.groupCode = groupCode;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String[] getGrantManageRoles() {
		return grantManageRoles;
	}

	public void setGrantManageRoles(String[] grantManageRoles) {
		this.grantManageRoles = grantManageRoles;
	}

	public String[] getGrantOtherRoles() {
		return grantOtherRoles;
	}

	public void setGrantOtherRoles(String[] grantOtherRoles) {
		this.grantOtherRoles = grantOtherRoles;
	}

	public List<Role> getOtherRoles() {
		return otherRoles;
	}

	public void setOtherRoles(List<Role> otherRoles) {
		this.otherRoles = otherRoles;
	}

	public List<Role> getManagerRoles() {
		return managerRoles;
	}

	public void setManagerRoles(List<Role> managerRoles) {
		this.managerRoles = managerRoles;
	}

}
